﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ElfTyping.General;
using Microsoft.Xna.Framework;

namespace ElfTyping.States
{
    public class FadingState : State
    {
        private const float FADE_OUT_TIME = 0.5f;
        private const float FADE_WAIT_TIME = 0.5f;
        private const float FADE_IN_TIME = 0.25f;
        private const float FADE_TEXT_OUT_TIME = 0.25f;

        protected const float MUSIC_FADE_OUT_TIME = 1.0f;
        private const float MUSIC_FADE_IN_TIME = 1.0f;

        protected enum FadeState
        {
            FADESTATE_OUT,
            FADESTATE_MIDDLE,
            FADESTATE_IN,
            FADESTATE_TEXT_OUT
        };

        static Rectangle view = new Rectangle(0, 0, 800, 600);

        protected bool fadingMusic = false;
        protected State previousState;
        protected State nextState;
        private float fadeAlpha = 0.0f;
        protected FadeState currentFadestate = FadeState.FADESTATE_OUT;
        private float dtCount = 0.0f;
        private bool drawHasBeenCalled = false;

        public FadingState(State previous, State next)
        {
            previousState = previous;
            nextState = next;
        }

        public override void InitializeState()
        {
            //if (!RobotGame.game().musicInfo.isBeingPlayed(nextState2.getMusicFile()))
            //{
            //    RobotGame.game().musicInfo.fadeOutMusic(MUSIC_FADE_OUT_TIME);
            //    fadingMusic = true;
            //}
        }

        public override void Tick(float dt)
        {
            float dAlpha;
            switch (currentFadestate)
            {
                case FadeState.FADESTATE_OUT:
                    if (drawHasBeenCalled)
                    {
                        dAlpha = dt / FADE_OUT_TIME;
                        fadeAlpha += dAlpha;
                        drawHasBeenCalled = false;
                    }

                    if (fadeAlpha >= 1)
                    {
                        fadeAlpha = 1;
                        currentFadestate = FadeState.FADESTATE_MIDDLE;
                    }

                    break;


                case FadeState.FADESTATE_MIDDLE:

                    if (drawHasBeenCalled)
                    {
                        dtCount += dt;
                        drawHasBeenCalled = false;
                    }

                    if (dtCount >= FADE_WAIT_TIME)
                    {
                        currentFadestate = FadeState.FADESTATE_IN;

                        if (fadingMusic)
                        {
                            //RobotGame.game().musicInfo.stopMusic();
                            //RobotGame.game().musicInfo.fadeInMusic(nextState2.getMusicFile(), MUSIC_FADE_IN_TIME);
                        }
                    }


                    break;



                case FadeState.FADESTATE_IN:
                    if (drawHasBeenCalled)
                    {
                        dAlpha = dt / FADE_IN_TIME;
                        fadeAlpha -= dAlpha;

                        drawHasBeenCalled = false;
                    }

                    if (fadeAlpha <= 0)
                    {
                        fadeAlpha = 0;

                        //if (textToDisplay == "")
                        {
                            base.ChangeStateAfterTick(nextState, false);
                        }
                        //else
                        //{
                        //    currentFadestate = FadeState.FADESTATE_TEXT_OUT;
                        //    dtCount = 0;
                        //}

                    }
                    break;

                case FadeState.FADESTATE_TEXT_OUT:
                    if (drawHasBeenCalled)
                    {
                        dtCount += dt;
                        drawHasBeenCalled = false;
                    }

                    if (dtCount > FADE_TEXT_OUT_TIME)
                    {
                        base.ChangeStateAfterTick(nextState, false);
                    }

                    break;
            }


            // causes stack overflow?
            base.Tick(dt);
        }

        public override void Draw(Camera camera)
        {
            drawHasBeenCalled = true;

	        // draw corresponding state
	        switch (currentFadestate)
	        {
	        case FadeState.FADESTATE_OUT:
		        previousState.Draw(camera);
		        break;
	        case FadeState.FADESTATE_MIDDLE:
		        break;
	        case FadeState.FADESTATE_IN:
	        case FadeState.FADESTATE_TEXT_OUT:
		        nextState.Draw(camera);
		        break;
	        }

	        // draw a semi transparent thing over it
            //view.draw(black, fadeAlpha);
            Color color = new Color(0, 0, 0, fadeAlpha);
            //camera.drawRect(view, black, color);
            camera.DrawRectangle(view, color);
	        // draw text
            //if ( !(textToDisplay == "") ) {
            //    switch (currentFadestate)
            //    {
            //    case FadeState.FADESTATE_OUT:
            //        camera.setFontColor(1, 1, 1, fadeAlpha);
            //        break;
            //    case FadeState.FADESTATE_MIDDLE:
            //    case FadeState.FADESTATE_IN:
            //        camera.setFontColor(1, 1, 1);
            //        break;
            //    case FadeState.FADESTATE_TEXT_OUT:
            //        camera.setFontColor(1, 1, 1,  (1 - dtCount / FADE_TEXT_OUT_TIME));
            //        break;
            //    }

            //    //Rect rect = Rect.makeRectLDRU(.1,0,.9,1);
            //    //ResourceManager.getFont().drawTextInRect(textToDisplay, rect);
            //    camera.useMenuFont();
            //    camera.drawCenteredText(textToDisplay, view, true, true);
            //    camera.useDefaultFont();
        }

        public override void HandleInput(InputInfo inputInfo)
        {
            // do nothing
        }
    }
}
